<?php
class Session extends Module{
	
	public $name = 'session';
	public $dependencies = array('db');
	public $type;
	public $available_types = array('database','files','php');
	public $sid = null;
	public $cookie_name;
	
	public function Session(&$application){
		$this->Module($application);
		if(!in_array(SESSION_TYPE, $this->available_types)){
			$this->app->err->fatal_error('Session type <strong>'.SESSION_TYPE.'</strong> is not defined.');
		}
		$this->type = SESSION_TYPE;
		$this->cookie_name = SESSION_COOKIE;
		$this->expire = SESSION_EXPIRE;
		$method = '_init_'.$this->type;
		$this->$method();
	}
	
	/* Session flash */
	public function set_flash($value){
		$this->set('session_flash', $value);
	}
	
	public function get_flash(){
		return $this->get('session_flash');
	}
	
	public function clear_flash(){
		$this->del('session_flash');
	}
	
	/* Delete */
	public function del($key){
		$method = '_del_'.$this->type;
		$this->$method($key, $val);
	}
	
	private function _del_php($key){
		unset($_SESSION[$key]);
	}
	
	private function _del_files($key){
		$this->_del_php($key);
	}
	
	private function _del_database($key){
		$this->db->delete_row('session_values', array('sid'=>$this->sid, 'key'=>$key));
	}
	
	/* Set */
	public function set($key, $val){
		$method = '_set_'.$this->type;
		$this->$method($key, $val);
	}
	
	private function _set_php($key, $val){
		$_SESSION[$key] = $val;
	}
	
	private function _set_files($key, $val){
		$this->_set_php($key, $val);
	}
	
	private function _set_database($key, $val){
		if(is_array($val)) $val = serialize($val);
		$test = $this->db->get_row('session_values', array('key'=>quote($key), 'sid'=>quote($this->sid)));
		if($test){
			$update = array('value'=>$val);
			$this->db->save_row('session_values', $update, $test['id']);
		}else{
			$insert = array('key'=>$key, 'value'=>$val, 'sid'=>$this->sid);
			$this->db->save_row('session_values', $insert);
		}
	}
	
	/* Get */
	public function get($key){
		$method = '_get_'.$this->type;
		return $this->$method($key);
	}
	
	private function _get_php($key){
		return $_SESSION['key'];
	}
	
	private function _get_files($key){
		return $this->_get_php($key);
	}
	
	private function _get_database($key){
		$value = $this->db->get_field('session_values', 'value', array('key'=>quote($key)));
		if(is_array(unserialize($value))){
			return unserialize($value);
		}else{
			return $value;
		}
	}
	
	/* Init */
	private function _init_php(){
		session_start();
		$this->sid = session_id();
	}
	
	private function _init_files(){
		if(!is_dir(SESSION_DIR)){
			$this->app->err->fatal_error('No session directory <strong>'.SESSION_DIR.'</strong>.');
		}
		if(!is_writeable(SESSION_DIR)){
			$this->app->err->fatal_error('Directory <strong>'.SESSION_DIR.'</strong> is not writeable.');
		}
		$this->_init_php();
	}
	
	private function _init_database(){
		$this->_create_tables();
		if($this->_check_cookie() && $this->_is_database_init()){//update already created session
			$this->sid = $this->_get_cookie();
			$this->_update_database();
		}else{//create new session
			$this->sid = md5(generate_code(50));
			setcookie($this->cookie_name,$this->sid,$this->expire,'/');
			$insert = array('sid'=>$this->sid,'date'=>time());
			$this->db->save_row('session', $insert);
		}
	}
	
	/* Database specific functions */
	private function _update_database(){
		$data = array('date'=>time());
		$this->db->save_row('session', $data, array('sid'=>$this->sid));
	}
	
	private function _is_database_init(){//daca exista in db sesiune cu id-ul din cookie
		$check = $this->db->get_row('session', array('sid'=>quote($this->_get_cookie())));
		return !empty($check);
	}
	
	private function _check_cookie(){
		return !empty($_COOKIE[$this->cookie_name]);
	}
	
	private function _get_cookie(){
		return $_COOKIE[$this->cookie_name];
	}
	
	private function _create_tables(){
		if(!$this->db->check_table('session', false)){
			$query = "CREATE TABLE IF NOT EXISTS `".DB_PREFIX."session` (
					  `id` int(11) NOT NULL auto_increment,
					  `sid` varchar(255) NOT NULL,
					  `date` int(11) NOT NULL,
					  PRIMARY KEY  (`id`),
					  KEY `sid` (`sid`)
					) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;";
			$this->db->query($query);
		}
		if(!$this->db->check_table('session_values', false)){
			$query = "CREATE TABLE IF NOT EXISTS `".DB_PREFIX."session_values` (
					  `id` int(11) NOT NULL auto_increment,
					  `sid` varchar(255) NOT NULL,
					  `key` varchar(255) NOT NULL,
					  `value` text NOT NULL,
					  PRIMARY KEY  (`id`),
					  KEY `sid` (`sid`)
					) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;";
			$this->db->query($query);
			$query = $query = "ALTER TABLE `".DB_PREFIX."session_values` ADD CONSTRAINT `".DB_PREFIX."session_values_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `".DB_PREFIX."session` (`sid`) ON DELETE CASCADE;";
			$this->db->query($query);
		}
	}
}
?>